#!/usr/bin/python
#-*- coding:utf-8 -*-

# data.py
#
# Copyright (c) 2007 Marcelo Lira dos Santos
#
# Author: Marcelo Lira dos Santos <setanta@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA

import gobject

INT = 0
AUR = 1
CAR = 2
FOR = 3
FIS = 4
AGI = 5
PER = 6

ATTRIBUTE_SHORT_NAMES = ('Int', 'Aur', 'Car', 'For', 'Fís', 'Agi', 'Per', '')
ATTRIBUTE_NAMES = ('Intelecto', 'Aura', 'Carisma', 'Força',
                   'Físico', 'Agilidade', 'Percepção')

class Base(gobject.GObject):
    def __init__(self, name='', id=-1):
        gobject.GObject.__init__(self)
        self.id = id
        self.name = name
        self.description = None
        self.image = None

    def __str__(self):
        return '%s\n%s' % (self.name, self.description)


class Race(Base):
    ATTRIBUTES = {'intelecto':0, 'aura':1, 'carisma':2, 'forca':3,
                  'fisico':4, 'agilidade':5, 'percepcao':6}

    def __init__(self, name, id=-1):
        Base.__init__(self, name, id)
        self.available_professions = []
        self.attribute_bonus = [0, 0, 0, 0, 0, 0, 0]
        self.base_speed = 0
        self.ef = 0
        self.base_height = 0
        self.base_weight = 0
        self.age = (0, 0)

    def set_attribute_bonus(self, attribute, value):
        self.attribute_bonus[Race.ATTRIBUTES[attribute]] = value

    def get_attribute_bonus(self):
        return self.attribute_bonus

    def calc_medium_age(self):
        return int((self.age[0] + self.age[1]) / 2)

    def calc_minmax_height(self):
        min_height = max_height = self.base_height
        min_height -= (min_height * 0.1)
        max_height += (max_height * 0.1)
        return min_height, max_height

    def calc_minmax_weight(self):
        min_weight = max_weight = self.base_weight
        min_weight -= (min_weight * 0.1)
        max_weight += (max_weight * 0.1)
        return min_weight, max_weight

    def get_medium_height(self):
        return float(self.base_height)

    def get_medium_weight(self):
        return float(self.base_weight)

    def __str__(self):
        return '%s\n%s\n%s\n%s\nvb:%d\nef:%d\nidade:%s\naltura:%d,peso:%d' % \
                    (self.name, self.description, str(self.available_professions),
                    str(self.attribute_bonus), self.base_speed, self.ef,
                    str(self.age), self.base_height, self.base_weight)


class Profession(Base):
    def __init__(self, name, prof_id=-1):
        Base.__init__(self, name, prof_id)
        self.eh = 0
        self.equipment = []
        self.posessions = (0, 0, 0)
        self.skill_points = 0
        self.weapon_points = 0
        self.combat_points = 0
        self.penalized_skill_group = -1
        self.specialization_skill = -1
        self.attribute_for_magic = -1
        self.spell_group = -1

    def __str__(self):
        return '%s\n%s\n%s\n%s\neh:%d\nph:%d\nghp:%s\nespH:%s\npa:%d,pc:%d' % \
                    (self.name, self.description, str(self.equipment),
                    str(self.posessions), self.eh, self.skill_points,
                    self.penalized_skill_group, self.specialization_skill,
                    self.weapon_points, self.combat_points)


class Specialization(Base):
    def __init__(self, name, id=-1):
        Base.__init__(self, name, id)
        self.profession = 0
        self.spell_group = 0
        self.technique_group = 0


class Skill(Base):
    def __init__(self, name, id=-1):
        Base.__init__(self, id)
        self.restricted = False
        self.has_specialization = False
        self.specialization_suggestions = None

    def __str__(self):
        return 'Skill: %s\nDescription: %s\nr: %s\ne: %s\nsuggestions: %s' % \
                    (self.name, self.description, str(self.restricted),
                    str(self.has_specialization), str(self.specialization_suggestions))


class Spell(Base):
    def __init__(self, name):
        Base.__init__(self, name)
        self.evocacao = None
        self.alcance = None
        self.duracao = None
        self.efeitos = {}

    def __str__(self):
        return '%s\n%s\n%s, %s, %s\n%s' % (self.name, self.description,
                    self.evocacao, self.alcance, self.duracao,
                    str(self.efeitos.items()))

# Equipamento ----------------------------------------------------------------
class Item(Base):
    def __init__(self, name):
        Base.__init__(self, name)
        self.price = 0
        self.description = None

    def __str__(self):
        return '%s\t%s\t%s' % \
                    (self.name, str(self.price), self.description)


class Weapon(Item):
    def __init__(self, name):
        Item.__init__(self, name)
        self.skill_id = None
        #self.handling = {}
        self.min_strength = 0
        self.min_damage = 0
        self.attack_defense = {'l' : 0, 'm' : 0, 'p' : 0}
        self.range = 0

    def __str__(self):
        return '%s\n%s\n%s\nfm:%d\nat:%s,dn:%d' % \
               (Item.__str__(self), self.skill_group,
                self.min_strength, self.attack_defense,
                self.damage, self.range)

class Defense(Item):
    def __init__(self, name):
        Item.__init__(self, name)
        self.type = None
        self.base_defense = 0
        self.absorption = 0

    def __str__(self):
        return '%s\ndb:%d\nab:%d' % \
               (Item.__str__(self), self.base_defense, self.absorption)

class Shield(Defense, Weapon):
    def __init__(self, name):
        Defense.__init__(self, name)
        Weapon.__init__(self, name)

    def __str__(self):
        return '%s\ndb:%d\nab:%d\n%s\nat:%s,dn:%d' % \
               (Item.__str__(self), self.base_defense, self.absorption,
                self.attack_defense, self.damage)


# Persona --------------------------------------------------------------------
class Persona(Base):
    ATTRIBUTE_PTS = 15
    MAGIC_PTS = 5
    ATTRIBUTE_SHORT2VALUE = {'Int' : 0, 'Aur' : 1, 'Car' : 2, 'For' : 3,
                             'Fís' : 4, 'Agi' : 5, 'Per' : 6}

    def __init__(self, name='', id=-1):
        Base.__init__(self, name, id)

        self.player = ''

        self.attributes = [0, 0, 0, 0, 0, 0, 0]
        self.karma = 0
        self.active_defense = 0
        self.passive_defense = 0
        self.max_eh = 0
        self.eh = 0
        self.ef = 0
        self.absorption = 0

        self.race = -1
        self.profession = -1
        self.specialization = -1
        self.level = 1

        self.skill_points = 0
        self.combat_points = 0
        self.weapon_points = 0
        self.magic_points = 0

        self.height = 0
        self.weight = 0
        self.age = 0

        self.eyes = ''
        self.hair = ''
        self.skin = ''
        self.appearance = ''

        self.god = -1
        self.social_class = ''
        self.place_of_origin = ''
        self.history = ''

        self.copper_coins = 0
        self.silver_coins = 0
        self.gold_coins = 0

        self.spells = {}
        self.equipment = {}
        self.skills = {}
        self.skills_specs = {}

    def __cmp__(self, persona2):
        if persona2 == None:
            return False
        return self.name == persona2.name

    def get_attributes_total(self):
        if self.attributes and self.race:
            return map(int.__add__, self.attributes, self.race.attribute_bonus)
        return None

    def get_attribute_by_short_name(self, short_name):
        att = self.ATTRIBUTE_SHORT2VALUE[short_name]
        return self.attributes[att] + self.race.attribute_bonus[att]

    def get_intelecto(self):
        return self.attributes[INT] + self.race.attribute_bonus[INT]

    def get_aura(self):
        return self.attributes[AUR] + self.race.attribute_bonus[AUR]

    def get_carisma(self):
        return self.attributes[CAR] + self.race.attribute_bonus[CAR]

    def get_forca(self):
        return self.attributes[FOR] + self.race.attribute_bonus[FOR]

    def get_fisico(self):
        return self.attributes[FIS] + self.race.attribute_bonus[FIS]

    def get_agilidade(self):
        return self.attributes[AGI] + self.race.attribute_bonus[AGI]

    def get_percepcao(self):
        return self.attributes[PER] + self.race.attribute_bonus[PER]

    def get_max_ef(self):
        return self.get_forca() + self.get_fisico() + self.race.ef

    def get_physical_resistance(self):
        return self.level + self.get_fisico()

    def get_magical_resistance(self):
        return self.level + self.get_aura()

    def get_speed(self):
        return self.race.base_speed + self.get_fisico()

    def get_karma(self):
        return self.get_aura() * (self.level + 1)

    def calc_defense(self):
        self.passive_defense = 0 # depende da protecao usada
        self.active_defense = self.passive_defense + \
                                      self.get_agilidade()
        return (self.active_defense, self.passive_defense)

    def calc_absorption(self):
        self.absorption = self.get_max_ef() # + armadura e elmo
        return self.absorption

    def calc_magic_points(self):
        if self.profession.attribute_for_magic == -1:
            return 0
        return self.attributes[self.profession.attribute_for_magic] + \
               self.MAGIC_PTS

# Registro de GOjects --------------------------------------------------------
gobject.type_register(Base)
gobject.type_register(Race)
gobject.type_register(Profession)
gobject.type_register(Specialization)
gobject.type_register(Skill)
gobject.type_register(Spell)
gobject.type_register(Item)
gobject.type_register(Weapon)
gobject.type_register(Defense)
gobject.type_register(Shield)
gobject.type_register(Persona)
